﻿using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http;
using TeamsPortal.Web.Controllers.Models;

namespace TeamsPortal.Web.Controllers.Formatters
{
    static class Test
    {
        //todo: move to the apropriate class
        public static byte[] ReadFully(this Stream input)
        {
            byte[] buffer = new byte[16 * 1024];
            using (MemoryStream ms = new MemoryStream())
            {
                int read;
                while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
                {
                    ms.Write(buffer, 0, read);
                }
                return ms.ToArray();
            }
        }
    }

    public class UploadImageModelFormatter : MediaTypeFormatter
    {
        public UploadImageModelFormatter()
        {
            SupportedMediaTypes.Add(new MediaTypeHeaderValue("multipart/form-data"));
            //SupportedMediaTypes.Add(new MediaTypeHeaderValue("image/jpeg"));
        }

        public override bool CanWriteType(Type type)
        {
            return false;
        }

        public override bool CanReadType(Type type)
        {
            return type == typeof(UploadImageModel);
        }

        public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
        {
            if (!content.IsMimeMultipartContent())
            {
                throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
            }

            var provider = new MultipartMemoryStreamProvider();
            var task = content.ReadAsMultipartAsync(provider).
                ContinueWith<object>(t =>
                {
                    var result = new UploadImageModel();
                    foreach (HttpContent part in provider.Contents)
                    {
                        string name = part.Headers.ContentDisposition.Name.Replace("\"", "");
                        string value;
                        switch (name)
                        {
                            case "X":
                                value = part.ReadAsStringAsync().Result;
                                result.X = int.Parse(value);
                                break;
                            case "Y":
                                value = part.ReadAsStringAsync().Result;
                                result.Y = int.Parse(value);
                                break;
                            case "Width":
                                value = part.ReadAsStringAsync().Result;
                                result.Width = int.Parse(value);
                                break;
                            case "Height":
                                value = part.ReadAsStringAsync().Result;
                                result.Height = int.Parse(value);
                                break;
                            case "RedirectUrl":
                                value = part.ReadAsStringAsync().Result;
                                result.RedirectUrl = value;
                                break;
                            //case "UserId":
                            //    value = part.ReadAsStringAsync().Result;
                            //    result.UserId = int.Parse(value);
                            //    break;
                            case "File":
                                Stream inputStream = part.ReadAsStreamAsync().Result;
                                result.ImageBytes = inputStream.ReadFully();
                                //result.File = new MemoryFile(part.ReadAsStreamAsync().Result,
                                //    part.Headers.ContentType.ToString(),
                                //    part.Headers.ContentDisposition.FileName);
                                //result.ImageStream = part.ReadAsStreamAsync().Result;
                                break;
                        }
                    }

                    return result;
                });

            return task;
        }
    }
}
